home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / source / fft.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-20  |  4.1 KB  |  213 lines

  1. /*
  2.  *  FFT.C -- Show FFT analyzer spectra
  3.  *
  4.  *  Copyright (C) 1991 by Alef Null. All rights reserved.
  5.  *  Author(s): Jarkko Vuori, OH2LNS
  6.  *  Modification(s):
  7.  */
  8.  
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <signal.h>
  13. #include <conio.h>
  14. #include <ctype.h>
  15. #include <math.h>
  16. #include "dspldrv.h"
  17. #include "serial.h"
  18.  
  19.  
  20. #define DX        512     // number of horisontal lines
  21. #define DY        256     // vertical lines
  22.  
  23. #define PORT        1        // default serial port number
  24. #define BAUD        19200   // baud rate
  25.  
  26. #define POINTS        1024    // number of points in FFT
  27.  
  28.  
  29. /* local program status */
  30. static struct {
  31.     unsigned ctrlC:1;
  32. } flags;
  33.  
  34. /* DSP CARD 3 FFT analyzer status */
  35. static struct {
  36.     long version,
  37.      samplef,
  38.      N;
  39. } card_status;
  40.  
  41.  
  42. /*
  43.  * CTRL-C handler
  44.  */
  45. void cdecl CtrlCHandler(void) {
  46.     flags.ctrlC = 1;
  47. }
  48.  
  49.  
  50. /*
  51.  * handle one word from DSP CARD 3
  52.  */
  53. void process(int wordno, long d) {
  54.     static double maxdB, prev_maxdB, xmaxdB, prev_xmaxdB;
  55.     double      dB;
  56.     int       bin;
  57.  
  58.     switch (wordno) {
  59.     case 1:
  60.     card_status.version = d;
  61.     break;
  62.  
  63.     case 2:
  64.     card_status.samplef = d;
  65.     break;
  66.  
  67.     case 3:
  68.     card_status.N        = d;
  69.     break;
  70.  
  71.     default:
  72.     bin = wordno-4;
  73.  
  74.     /* one whole word received, first calculate dB */
  75.     dB  = d > 0 ? 10.0*log10((double)d) : 0.0;
  76.  
  77.     /* then check if it was maximum */
  78.     if (dB > maxdB && bin > 3) {
  79.         maxdB  = dB;
  80.         xmaxdB = (double)bin;
  81.     }
  82.     if (dB > prev_maxdB && bin > 3 && abs(bin-(int)xmaxdB) > 10) {
  83.         prev_maxdB    = dB;
  84.         prev_xmaxdB = (double)bin;
  85.     }
  86.  
  87.     /* plot it */
  88.     PlotPoint(bin, (int)(3.0*dB+.5));
  89.     break;
  90.  
  91.     case POINTS/2+3:
  92.     /* last word received */
  93.     PlotStatus(2*card_status.N, card_status.samplef);
  94.     PlotMarker((int)xmaxdB, (int)(3.0*maxdB+.5), xmaxdB*(double)card_status.samplef/(double)POINTS, maxdB,
  95.            (int)prev_xmaxdB, (int)(3.0*prev_maxdB+.5), prev_xmaxdB*(double)card_status.samplef/(double)POINTS, prev_maxdB);
  96.     prev_maxdB = maxdB = 0.0;
  97.     break;
  98.     }
  99. }
  100.  
  101.  
  102. int cdecl main(int argc, char *argv[]) {
  103.     long    d;
  104.     int     c, state = 0, port = PORT;
  105.     char    option;
  106.  
  107.     /* parse arguments */
  108.     argc--; argv++;
  109.     while(argc > 0) {
  110.     switch(**argv) {
  111.     case '-':
  112.         switch(option = *(++(*argv))) {
  113.         /* port selection */
  114.         case 'p':
  115.         case 'P':
  116.         port = atoi(++(*argv));
  117.         break;
  118.  
  119.         default:
  120.         fprintf(stderr, "unknown option '%c', type 'fft ?' to get the allowed options\n", option);
  121.         break;
  122.         }
  123.         break;
  124.  
  125.     case '?':
  126.         fprintf(stderr, "usage: fft [-p<portno>]\n");
  127.         fprintf(stderr, "\t-p<portno> uses the specified (1 (default) or 2) serial port\n");
  128.         return (0);
  129.         break;
  130.  
  131.     default:
  132.         fprintf(stderr, "option must be preceded by '-'\n");
  133.         break;
  134.     }
  135.  
  136.     argc--; argv++;
  137.     }
  138.  
  139.     signal(SIGINT, CtrlCHandler);
  140.     if (!OpenSerial(port, BAUD)) {
  141.     fprintf(stderr, "can't open file serial port COM%d\n", port);
  142.     return (1);
  143.     }
  144.  
  145.     if (InitDspl(DX, DY)) {
  146.     fprintf(stderr, "%s: no support for needed graphics device\n", __FILE__);
  147.     CloseSerial();
  148.     return (1);
  149.     }
  150.  
  151.     while (!flags.ctrlC) {
  152.     /* check if user want something */
  153.     if (kbhit()) {
  154.         c = getch();
  155.  
  156.         if (c == '.')
  157.         break;
  158.         else if (c == '+' || c == '-')
  159.         WriteSerial(c);
  160.     }
  161.  
  162.     /* then check if DSP CARD 3 wants something */
  163.     if ((c = ReadSerial()) != -1)
  164.         switch (state) {
  165.         case 0:    // wait for header
  166.         if (c == 0x64)
  167.             state++;
  168.         break;
  169.  
  170.         case 1:
  171.         if (c == 0x09)
  172.             state++;
  173.         else
  174.             state = 0;
  175.         break;
  176.  
  177.         case 2:
  178.         if (c == 0x01)
  179.             state++;
  180.         else
  181.             state = 0;
  182.         break;
  183.  
  184.         default:    // read data
  185.         /* collect three bytes (24 bits) */
  186.         switch (state % 3) {
  187.         case 0:
  188.             d = (long)c;
  189.             break;
  190.  
  191.         case 1:
  192.             d |= (long)c << 8;
  193.             break;
  194.  
  195.         case 2:
  196.             d |= (long)c << 16;
  197.  
  198.             process(state/3, d);
  199.             break;
  200.         }
  201.  
  202.         /* and finally, check if it was the last line of spectra */
  203.         if (++state >= 3*(POINTS/2+1+3))
  204.             state = 0;
  205.         break;
  206.         }
  207.     }
  208.  
  209.     CloseSerial();
  210.     ReleaseDspl();
  211.     return (0);
  212. }
  213.